package com.babel.util.delayer;

import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.DelayQueue;
import java.util.concurrent.TimeUnit;

public class Cache<K, V> {
	
	/*protected SimpleLogger logger = SimpleLogger.getLogger(this.getClass());*/

	private ConcurrentMap<K, V> cacheObjMap = new ConcurrentHashMap<K, V>();

	private DelayQueue<DelayItem<Pair<K, V>>> q = new DelayQueue<DelayItem<Pair<K, V>>>();
	private static Cache<Object, Object> cc;
	private Thread daemonThread;

	public Cache() {

		Runnable daemonTask = new Runnable() {
			public void run() {
				daemonCheck();
			}
		};

		daemonThread = new Thread(daemonTask);
		daemonThread.setDaemon(true);
		daemonThread.setName("Cache Daemon");
		daemonThread.start();
	}

	public static Cache<Object, Object> isInstance() {

		synchronized (Cache.class) {
			if (cc == null)
				cc = new Cache<Object, Object>();
		}
		return cc;
	}

	private void daemonCheck() {

		while (true) {
			try {
				DelayItem<Pair<K, V>> delayItem = q.take();
				if (delayItem != null) {
					// 超时对象处理
					Pair<K, V> pair = delayItem.getItem();
					cacheObjMap.remove(pair.first);
					/*logger.info("d." + pair.first + "=====" + pair.second);*/
				}
			} catch (InterruptedException e) {
			/*	logger.error(e.getMessage(), e);*/
				break;
			}
		}

	}

	// 添加缓存对象
	public void put(K key, V value, long time) {
		V oldValue = cacheObjMap.put(key, value);

		if (oldValue != null)
			q.remove(key);

		TimeUnit unit = TimeUnit.SECONDS;
		long nanoTime = TimeUnit.NANOSECONDS.convert(time, unit);
		q.put(new DelayItem<Pair<K, V>>(new Pair<K, V>(key, value), nanoTime));
	}

	public V get(K key) {
		return cacheObjMap.get(key);
	}

	public void updata(K key, V value) {
		cacheObjMap.put(key, value);
	}

	public boolean remove(K key) {
		V value = cacheObjMap.get(key);
		return cacheObjMap.remove(key, value); // compare and remove
	}
	
}

